/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cip.esymons.tramite.bc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.cip.esymons.general.util.ControladorAbstracto;
import org.cip.esymons.tramite.be.DocRequerido;
import org.cip.esymons.tramite.be.DocumentoIncluido;
import org.cip.esymons.tramite.be.EnumAccionOperacion;
import org.cip.esymons.tramite.be.EnumEstadoOperacion;
import org.cip.esymons.tramite.be.Operacion;
import org.cip.esymons.tramite.be.Procedimiento;
import org.cip.esymons.tramite.be.Transaccion;

/**
 *
 * @author ChristianATE
 */
@Stateless
public class OperacionFacade implements OperacionFacadeLocal {

    @PersistenceContext
    private EntityManager em;
    @EJB
    ProcedimientoFacadeLocal proc;
    @EJB
    ResponsableProcFacadeLocal resFacade;
    @EJB
    DocRequeridoFacadeLocal docReqFacade;
    @EJB
    DocumentoIncluidoFacadeLocal docIncFacade;
    @EJB
    TransaccionFacadeLocal transFacade;

    public void create(Operacion operacion) {
        em.persist(operacion);
    }

    public void edit(Operacion operacion) {
        em.merge(operacion);
    }

    public void remove(Operacion operacion) {
        em.remove(em.merge(operacion));
    }

    public Operacion find(Object id) {
        return em.find(Operacion.class, id);
    }

    public Operacion crearOperacion(Transaccion tran) {
        Operacion oper = new Operacion(new Date(), "Inicio", EnumEstadoOperacion.Iniciado, tran, proc.buscarInicioXTramite(tran.getFkTrmCodigo()));
        create(oper);
        return oper;
    }

    public void generarOperaciones(Transaccion tran) {
        EnumEstadoOperacion estado = EnumEstadoOperacion.Iniciado;
        List<Procedimiento> procedimientos;
        procedimientos = proc.findXTrmite(tran.getFkTrmCodigo());

        for (Procedimiento pro : procedimientos) {
            create(new Operacion(new Date(), "", estado, tran, pro, resFacade.buscarDesocupado(pro)));
            estado = EnumEstadoOperacion.archivado;
        }
    }

    public List<Operacion> findAll() {
        return em.createQuery("select object(o) from Operacion as o").getResultList();
    }

    public void Aprobar(Transaccion trans) {
        try {
            List<Procedimiento> procedimientos = new ArrayList<Procedimiento>();
            trans.getOperacionActiva().setOpeEstado(EnumEstadoOperacion.Tramitado);
            trans.getOperacionActiva().setOpeFechTram(new Date());
            edit(trans.getOperacionActiva());
            procedimientos = proc.nextProced(trans);

            if (procedimientos.isEmpty()) {
                if (listarXTransaccion(trans).isEmpty()) {
                    trans.setTraEstado(true);
                    transFacade.edit(trans);
                }
            }

            for (Procedimiento pro : procedimientos) {
                Operacion oper = new Operacion(EnumEstadoOperacion.Iniciado, new Date(), "", trans, pro, resFacade.buscarDesocupado(pro));
                create(oper);
                for (DocRequerido docReq : docReqFacade.listarDocumentoXProcedimiento(pro)) {
                    for (DocumentoIncluido docs : docIncFacade.listarXTransaccion(trans)) {
                        if (docReq.getFkTdoCodigo().equals(docs.getFkDocCodigo().getFkTdoCodigo())) {
                            docIncFacade.create(new DocumentoIncluido("", trans.getFkExpCodigo(), oper, docs.getFkDocCodigo()));
                        }
                    }
                }
            }
        } catch (Exception e) {
            ControladorAbstracto.error(e.getMessage());
        }
    }

    public void AprobarDocExt(Operacion op) {
        try {
            List<Operacion> operaciones;
            operaciones = new ArrayList<Operacion>();
            op.setOpeEstado(EnumEstadoOperacion.Tramitado);
            op.setOpeFechTram(new Date());
            edit(op);

            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkTraCodigo t");
            sb.append(" where (o.opeEstado=?1 or o.opeEstado=?3 or o.opeEstado=?5 or o.opeEstado=?6) and o.fkTraCodigo=?2 and o.opeAccion<>?4");

            q = em.createQuery(sb.toString());

            q.setParameter(1, EnumEstadoOperacion.recepcionado);
            q.setParameter(2, op.getFkTraCodigo());
            q.setParameter(3, EnumEstadoOperacion.Iniciado);
            q.setParameter(4, EnumAccionOperacion.Solo_Lectura);
            q.setParameter(5, EnumEstadoOperacion.Transferido);
            q.setParameter(6, EnumEstadoOperacion.respondido);

            operaciones = q.getResultList();

            if(operaciones.size()<1){
                op.getFkTraCodigo().setTraEstado(true);
                transFacade.edit(op.getFkTraCodigo());
            }

        } catch (Exception e) {
            ControladorAbstracto.error(e.getMessage());
        }
    }

    public Operacion buscarXCobro(Transaccion tra) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkTraCodigo t");
            sb.append(" where o.opeDescripcion=?1 and o.opeEstado=?3 and o.fkTraCodigo=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, "Inicio");
            q.setParameter(2, tra);
            q.setParameter(3, EnumEstadoOperacion.Iniciado);

            return (Operacion) q.getSingleResult();
        } catch (Exception ex) {
            return null;
        }
    }

    public List<Operacion> listarArchExterXEmpleado(Long empl) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkTraCodigo t inner Join o.fkResCodigo r ");
            sb.append(" where o.opeEstado=?3 and r.fkPerCodigopna=?1 and t.fkTrmCodigo.trmNombre=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, empl);
            q.setParameter(2, "Documento Externo");
            q.setParameter(3, EnumEstadoOperacion.archivado);

            return q.getResultList();

        } catch (Exception ex) {
            return new ArrayList();
        }
    }

    public List<Operacion> listarExterXEmpleado(Long empl) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkTraCodigo t inner Join o.fkResCodigo r ");
            sb.append(" where o.opeEstado<>?3 and r.fkPerCodigopna=?1 and t.fkTrmCodigo.trmNombre=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, empl);
            q.setParameter(2, "Documento Externo");
            q.setParameter(3, EnumEstadoOperacion.archivado);

            return q.getResultList();

        } catch (Exception ex) {
            return new ArrayList();
        }
    }

    public Operacion buscarXTransaccion(Transaccion tra, Long res) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkTraCodigo t inner Join o.fkResCodigo r ");
            sb.append(" where o.opeEstado=?3 and r.fkPerCodigopna=?1 and o.fkTraCodigo=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, res);
            q.setParameter(2, tra);
            q.setParameter(3, EnumEstadoOperacion.Iniciado);

            return (Operacion) q.getSingleResult();
        } catch (Exception ex) {
            return null;
        }
    }

    public Operacion buscarXTransaccion(Transaccion tra) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o ");
            sb.append(" where o.opeEstado=?1 and o.fkTraCodigo=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, EnumEstadoOperacion.Iniciado);
            q.setParameter(2, tra);

            return (Operacion) q.getSingleResult();
        } catch (Exception ex) {
            return null;
        }
    }

    public Operacion buscarIniXTransaccion(Transaccion tra) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o inner Join o.fkProCodigo p ");
            sb.append(" where p.proNombre=?1 and o.fkTraCodigo=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, "Inicio");
            q.setParameter(2, tra);

            return (Operacion) q.getSingleResult();
        } catch (Exception ex) {
            return new Operacion();
        }
    }

    public List<Operacion> listarXTransaccion(Transaccion tra) {
        try {
            Query q = null;
            StringBuilder sb = new StringBuilder();
            sb.append(" select o");
            sb.append(" from Operacion o ");
            sb.append(" where (o.opeEstado=?1 or o.opeEstado=?3) and o.fkTraCodigo=?2");

            q = em.createQuery(sb.toString());

            q.setParameter(1, EnumEstadoOperacion.Iniciado);
            q.setParameter(2, tra);
            q.setParameter(3, EnumEstadoOperacion.recepcionado);

            return q.getResultList();
        } catch (Exception ex) {
            return new ArrayList<Operacion>();
        }
    }
}
